/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Initial Developer of the Original Code is
*   Nick Kreeger
* Portions created by the Initial Developer are Copyright (C) 2006-2007
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*   Nick Kreeger <nick.kreeger@park.edu>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */

#import "MessageComposeService.h"
#import "MessageHeader.h"
#import "CompositionWindowController.h"
#import "NSString+Utils.h"
#import "CHBrowserView.h"

#import "nsIMsgAccountManager.h"
#import "nsIMsgAccount.h"
#import "nsIMsgIdentity.h"
#import "nsIMsgComposeService.h"
#import "nsIMsgComposeParams.h"
#import "nsIMsgMailSession.h"
#import "nsIMsgWindow.h"
#import "nsIDOMWindow.h"
#import "nsIDOMWindowInternal.h"
#import "nsMsgBaseCID.h"
#import "nsMsgCompCID.h"
#import "nsISupportsArray.h"
#import "nsCOMPtr.h"

#import "nsIDocShell.h"

static MessageComposeService* kMessageComposeServiceSingleton = nil;

@interface MessageComposeService(Private)

-(void)initializeComposerTo:(NSString*)toContacts cc:(NSString*)ccContacts;
-(void)initializeComposerForUri:(NSString*)aMessageUri compFormat:(MSG_ComposeType)aCompType;
-(BOOL)getCurrentMsgAccountIdentity:(nsIMsgIdentity**)aRetVal;

@end

@implementation MessageComposeService

+(id)sharedComposeService
{
  if (!kMessageComposeServiceSingleton)
    kMessageComposeServiceSingleton = [[self alloc] init];
  
  return kMessageComposeServiceSingleton;
}

-(id)init
{
  if ((self = [super init]))
  {
    mMailWindowController = nil;
    mComposerWindows = [[NSMutableArray alloc] init];
  }
  
  return self;
}

-(void)dealloc
{
  [mComposerWindows release];
  [super dealloc];
}

-(void)setWindowController:(MailWindowController*)aWindowController
{
  mMailWindowController = aWindowController;
}

//XXX rename this, we aren't always creating a new window
-(void)createNewMessageTo:(NSString*)inToContacts cc:(NSString*)inCcContacts
{
  //
  //
  // XXX - |Contact| is there, but its not a used interface.
  //
  //
  
  // If there is an active window, add the 'to:' contacts to the window
  if ([mComposerWindows count] > 0)
  {
    BOOL foundMainWindow = NO;
    for (unsigned int i = 0; i < [mComposerWindows count] && !foundMainWindow; i++)
    {
      CompositionWindowController* compWinController = [mComposerWindows objectAtIndex:i];
      
      if ([[compWinController window] isMainWindow])
      {
        [compWinController addToContacts:inToContacts];
        foundMainWindow = YES;
      }
    }
    
    // If we didn't find the main window, access the last opened composer (the last index in the array).
    if (!foundMainWindow)
      [(CompositionWindowController*)[mComposerWindows objectAtIndex:[mComposerWindows count] - 1] addToContacts:inToContacts];
  }
  
  // Create a new composer window with the contacts.
  else
    [self initializeComposerTo:inToContacts cc:inCcContacts];
}

-(void)createNewMessage
{
  [self initializeComposerForUri:NULL compFormat:nsIMsgCompType::New];
}

-(void)replyToMessageUri:(NSString*)aMessageUri
{
  [self initializeComposerForUri:aMessageUri compFormat:nsIMsgCompType::Reply];
}

-(void)replyToAllMessageUri:(NSString*)aMessageUri
{
  [self initializeComposerForUri:aMessageUri compFormat:nsIMsgCompType::ReplyAll];
}

-(void)forwardMessageUri:(NSString*)aMessageUri
{
  // We should really find out if the message is HTML, if it is and can't be filtered
  // we should just forward as an attachment.
  [self initializeComposerForUri:aMessageUri compFormat:nsIMsgCompType::ForwardInline];
}

-(void)initializeComposerTo:(NSString*)toContacts cc:(NSString*)ccContacts
{
  nsresult rv;
  nsCOMPtr<nsIMsgComposeService> composeService = do_GetService(NS_MSGCOMPOSESERVICE_CONTRACTID, &rv);
  if (NS_FAILED(rv))
    return;
  
  nsCOMPtr<nsIMsgIdentity> defaultIdentity;
  if ([self getCurrentMsgAccountIdentity:getter_AddRefs(defaultIdentity)] && defaultIdentity)
  {
    nsCOMPtr<nsIMsgComposeParams> composeParams = do_CreateInstance(NS_MSGCOMPOSEPARAMS_CONTRACTID, &rv);
    if (NS_SUCCEEDED(rv) && composeParams)
    {
      composeParams->SetType(nsIMsgCompType::New);
      composeParams->SetFormat(nsIMsgCompFormat::PlainText);
      composeParams->SetIdentity(defaultIdentity);
     
      nsCOMPtr<nsIMsgCompFields> msgCompFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID ,&rv);
      if (NS_SUCCEEDED(rv) && msgCompFields)
      {
        if (toContacts)
        {
          nsAutoString toStr;
          [toContacts assignTo_nsAString:toStr];
          msgCompFields->SetTo(toStr);
        }
        if (ccContacts)
        {
          nsAutoString ccStr;
          [ccContacts assignTo_nsAString:ccStr];
          msgCompFields->SetCc(ccStr);
        }
        composeParams->SetComposeFields(msgCompFields);
        
        composeService->OpenComposeWindowWithParams(NULL, composeParams);
      }
    }
  }
}

-(void)initializeComposerForUri:(NSString*)aMessageUri compFormat:(MSG_ComposeType)aCompType
{
  nsresult rv;
  nsCOMPtr<nsIMsgComposeService> composeService = do_GetService(NS_MSGCOMPOSESERVICE_CONTRACTID, &rv);
  if (NS_FAILED(rv))
    return;
  
  nsCOMPtr<nsIMsgIdentity> defaultIdentity;
  if (![self getCurrentMsgAccountIdentity:getter_AddRefs(defaultIdentity)] && !defaultIdentity)
    return;
  
  // Note the hard coded |nsIMsgCompFormat::PlainText| statement....
  composeService->OpenComposeWindow(nsnull, 
                                    (aMessageUri ? [aMessageUri UTF8String] : NULL), 
                                    aCompType,
                                    nsIMsgCompFormat::PlainText, 
                                    defaultIdentity,
                                    nsnull);
}

-(BOOL)getCurrentMsgAccountIdentity:(nsIMsgIdentity**)aRetVal
{
  nsresult rv;
  nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
  NS_ENSURE_SUCCESS(rv, NO);

  nsCOMPtr<nsIMsgAccount> account;
  nsCOMPtr<nsIMsgAccount> defaultAccount;
  accountManager->GetDefaultAccount(getter_AddRefs(defaultAccount));
  
  NSString* accountKey = [mMailWindowController selectedAccountKey];
  if (accountKey)
    rv = accountManager->GetAccount([accountKey UTF8String], getter_AddRefs(account));
  else
    account = defaultAccount;
  
  NS_ENSURE_SUCCESS(rv, NO);
  
  nsCOMPtr<nsIMsgIdentity> defaultIdentity;
  rv = account->GetDefaultIdentity(getter_AddRefs(defaultIdentity));
  NS_ENSURE_SUCCESS(rv, NO);
  
  // Last ditch effort, if we didn't find a identity and this isn't the default account,
  // get the identity from the default account. This is usually the case when trying to
  // find an identity for the local folders account.
  if (!defaultIdentity && account != defaultAccount)
  {
    account = defaultAccount;
    rv = account->GetDefaultIdentity(getter_AddRefs(defaultIdentity));
    if (NS_FAILED(rv) || !defaultIdentity)
      return NO;
  }
  
  NS_ADDREF(*aRetVal = defaultIdentity);
  return YES;
}

@end
